<?php
    class WeChat{
		private $_appid;
		private $_appsecret;
        private $_token;
		private $_tuling_key;//图灵 API_KEY
		function __construct($appid,$appsecret,$token,$tuling_key){
			$this -> _appid = $appid;
			$this -> _appsecret = $appsecret;
            $this -> _token = $token;
			$this -> _tuling_key = $tuling_key;
 		}
        //第一次接入验证
        public function valid()
        {
            $echoStr = $_GET["echostr"];
    
            //valid signature , option
            if($this->checkSignature()){
                echo $echoStr;
                exit;
            }
        }
        private function checkSignature()
        {
            $signature = $_GET["signature"];
            $timestamp = $_GET["timestamp"];
            $nonce = $_GET["nonce"];
            $token = $this -> _token;
            $tmpArr = array($token, $timestamp, $nonce);
            // use SORT_STRING rule
            sort($tmpArr, SORT_STRING);
            $tmpStr = implode( $tmpArr );
            $tmpStr = sha1( $tmpStr );
    		
            //   echo $tmpStr.'--'.$signature;
            if( $tmpStr == $signature ){
                return true;
            }else{
                return false;
            }
        }
		//获取       ACCESS_TOKEN
		private function getAccessToken($access_token = "./access_token"){
			$token_time = 7200;
			if(file_exists($access_token) && time() - filemtime($access_token) < $token_time){
				return file_get_contents($access_token);
			}
			$url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this -> _appid}&secret={$this -> _appsecret}";
			$result = $this-> _request($url);
			if(!$result){
				return false;
			}
			$result_obj = json_decode($result);
			//写入文件
			file_put_contents($access_token ,$result_obj -> access_token);
			return  $result_obj -> access_token;
		}
		//获取   ticket
		private function getticket($sceneid,$type = 'temp',$expire_seconds = 604800){
			$token = $this -> getAccessToken();//获取TOKEN
			if($type == 'temp'){
				$data = '{"expire_seconds":'.$expire_seconds.',"action_name":"QR_SCENE","action_info":{"scene":{"scene_id":'.$sceneid.'}}}';
				$url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=".$token;
			}else{
				$data = '{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": '.$sceneid.'}}}';
				$url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=".$token;
			}
			$content = $this -> _request($url,true,"post",$data);
			if(!$content){
				return false;
			}
			$content_obj = json_decode ($content);
			return $content_obj -> ticket;
		}
		//获取 QR二维码
		public function getQRcode($sceneid,$type = 'temp', $expire_seconds = 604800){
			$ticket = $this -> getticket($sceneid,$type,$expire_seconds);
			$url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=".urlencode($ticket);
			$QRcode = $this -> _request($url);
			return $QRcode;
		} 
        //创建自定义菜单
		public function createMenu($menu){
            $accesstoken = $this -> getAccessToken();
			$curl = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token='.$accesstoken;
			$content = json_decode($this->_request($curl,true,'POST',$menu));
            if($content->errcode == 0){
				echo "菜单成功创建<br/>";
            }else{
                echo "菜单创建失败<br/>";
            }
			print_r($content);
        }
        //删除自定义菜单
		public function deleteMenu(){
			$curl = 'https://api.weixin.qq.com/cgi-bin/menu/delete?access_token='.$this->getAccessToken();
			$content = json_decode($this->_request($curl,true,'GET'));
			if($content->errcode == 0)
				echo "菜单已删除";
		}
		//处理消息
		public function responseMsg()
		{
			//get post data, May be due to the different environments
			$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
			libxml_disable_entity_loader(true);
			$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
			$MsgType = $postObj -> MsgType;
			if($MsgType == "event"){
				$Event = $postObj -> Event; //处理事件类型的消息
				switch($Event){
					case 'subscribe':
						$this -> doSubscribe($postObj);//关注
						exit;
					case 'unsubscribe':
						$this -> doUnsubscribe($postObj);//取消关注
						exit;
					case 'SCAN':
						$this -> doScan($postObj);//扫描二维码事件
						exit;
					case 'LOCATION':
						$this -> doLocation($postObj);//上报地理位置事件
						exit;
					case 'CLICK':
						$this -> doClick($postObj);//点击菜单事件
						exit;
					case 'VIEW':
						$this -> doView($postObj);//点击菜单链接跳转事件
						exit;
				}
			}else{
				switch($MsgType){ //处理不同类型的消息
					case 'text':
							$this -> doText($postObj);	//文本类
							exit;
					case 'image';
							$this -> doImg($postObj);//图片类
							exit;
					case 'voice';
							$this -> doVoice($postObj);//语音类
							exit;
					case 'video':
							$this -> doVideo($postObj);//视频类
							exit;
					case 'location':
							$this -> doLocation($postObj);//位置类
							break;
					default:
						;
				}
			}	
		}
		//用户关注时作的处理
        private function doSubscribe($postObj){
        	$contentStr = "欢迎关注我的公众账号"; 
            $this -> _sendMsg($postObj,$contentStr);
        }
		//用户取消关注时所作的处理
		private function doUnsubscribe($postObj){
			
		}
		//自定义菜单点击事件
		private function doClick($postObj){
			
		}
		//自定义菜单点击跳转事件
		private function doView($postObj){
			
		}
		//用户发送地理位置事件
		private function doLocation(){
			
		}
		//发送图文消息
		private function News($postObj,$res = ""){
			if(!empty($res)){
				for($i = 0;$i<5;$i++){
					$title[$i] = $res -> list[$i] -> article;
					$desc[$i] = "";
					$picurl[$i] = $res -> list[$i] ->icon;
					$url[$i] = $res -> list[$i] -> detailurl;
				}
			}
			$news_item_tpl = '
				<item>
				<Title><![CDATA[%s]]></Title>
				<Description><![CDATA[%s]]></Description>
				<PicUrl><![CDATA[%s]]></PicUrl>
				<Url><![CDATA[%s]]></Url>
				</item>';
            $news_list = '';
            for($i = 0;$i<5;$i++){
				$news_list.= sprintf($news_item_tpl,$title[$i],$desc[$i],$picurl[$i],$url[$i]);
			}
			$this ->_sendMsg($postObj,$news_list,"news");
		}
		//处理发送的文本消息
		private function doText($postObj,$data = ""){
            if(empty($data)){
            	$an = $postObj -> Content;
            }else{
            	$an = $data;
            }
            switch($an){
                //关键词回复
                case '你好':
					$contentStr = '你好啊';
					break;
				case '空消息':
					$contentStr = "偶木有收到消息";
					break;
				default:
					//自动回复
					$url = "http://www.tuling123.com/openapi/api?key=".$this -> _tuling_key."&info=".$an;
					$res = $this -> _request($url,false);
					$res = json_decode($res);
                	switch($res ->code){
                        case '100000'://文本类消息
                        	$contentStr = $res->text;
                        	$this -> _sendMsg($postObj,$contentStr);
                        	exit;
                        case '200000'://链接类
                        	$contentStr = $res->text;
                        	$contentStr.= $res->url;
                        	$this -> _sendMsg($postObj,$contentStr);
                        case '302000'://新闻类
							$this -> news($postObj,$res);
                        	exit;
                        default :
                        	break;
               		 }
					
			}
			$this -> _sendMsg($postObj,$contentStr);
		} 
		//处理发送的图片
		private function doImg($postObj){
			
		}
		//处理用户的语音信息 --> 需要开启语音识别
		private function doVoice($postObj){
			if(!empty($postObj -> Recognition)){
				//语音识别不为空
				$data = $postObj -> Recognition;
				$this -> doText($postObj,$data);
			}else{
				$data = "空消息";
				$this -> doText($postObj,$data);
			}
		}
        //发送消息
		private function _sendMsg($postObj,$contentStr,$msgType = "text"){
			$fromUsername = $postObj -> FromUserName;
			$toUsername = $postObj -> ToUserName;
			$time = time();
			if($msgType == "news"){
				//发送图文消息
				$newstpl = '<xml>
								<ToUserName><![CDATA[%s]]></ToUserName>
								<FromUserName><![CDATA[%s]]></FromUserName>
								<CreateTime>%s</CreateTime>
								<MsgType><![CDATA[news]]></MsgType>
								<ArticleCount>%s</ArticleCount>
								<Articles>
								%s;
								</Articles>
								</xml> ';
				echo sprintf($newstpl,$fromUsername,$toUsername,$time,5,$contentStr);
			}else{
				$textTpl = "<xml>
								<ToUserName><![CDATA[%s]]></ToUserName>
								<FromUserName><![CDATA[%s]]></FromUserName>
								<CreateTime>%s</CreateTime>
								<MsgType><![CDATA[%s]]></MsgType>
								<Content><![CDATA[%s]]></Content>
								</xml>"; 
				echo sprintf($textTpl,$fromUsername,$toUsername,$time,$msgType,$contentStr);
			}
		}
		
		//请求    CURL 函数
        private function _request($curl, $https = true, $method = 'GET', $data = null){
			$ch = curl_init(); // 初始化curl
			curl_setopt($ch, CURLOPT_URL, $curl); //设置访问的 URL
			curl_setopt($ch, CURLOPT_HEADER, false); //放弃 URL 的头信息
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //返回字符串，而不直接输出
			if($https){ //判断是否是使用 https 协议
				curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //不做服务器的验证
				curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);  //做服务器的证书验证
			}
			if($method == 'POST'){ //是否是 POST 请求
				curl_setopt($ch, CURLOPT_POST, true); //设置为 POST 请求
				curl_setopt($ch, CURLOPT_POSTFIELDS, $data); //设置POST的请求数据
			}
			$content = curl_exec($ch); //开始访问指定URL
			curl_close($ch);//关闭 cURL 释放资源
			return $content;
		}
		
	}
?>